﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Collections.Specialized;

namespace MobiMenu.Restaurant.Web.Utility
{
    /// <summary>
    ///RequestHelper 的摘要说明
    /// </summary>
    public static class RequestHelper
    {
        public static char[] ParamsSeparator = new char[] { ',' };

        public static DateTime EarliestDateTime = new DateTime(2012, 1, 1);

        public static string MobiMenuConnectionString = "MobiMenuConnectionString";

        public const string RowsKey = "list";

        public const string SuccessKey = "success";

        public const string ErrorKey = "error";

        public const string TotalKey = "total";

        public const string PageCountKey = "pageCount";

        public const string DataKey = "data";

        public const string SortFieldKey = "sortField";

        public const string SortByDescKey = "sortByDesc";

        public const string PageNoKey = "pageNo";

        public const string PageSizeKey = "pageSize";

        //public const string QueryDicKey = "queryDic";

        public const string OperationTypeKey = "method";

        public const string SelectOperationKey = "select";

        public const string SelectAllOperationKey = "selectAll";

        public const string UpdateOperationKey = "update";

        public const string InsertOperationKey = "insert";

        public const string DeleteOperationKey = "delete";

        public const string InsertJsonDataKey = "insertJsonData";

        public const string DeleteIdsKey = "deleteIds";

        private static HashSet<string> _reservedKeys;

        private static object _lockObj = new object();


        public static HashSet<string> ReservedKeys
        {
            get
            {
                if (_reservedKeys == null)
                {
                    lock (_lockObj)
                    {
                        if (_reservedKeys == null)
                        {
                            _reservedKeys = new HashSet<string>() { 
                            SortFieldKey,
                            SortByDescKey,
                            PageSizeKey,
                            PageNoKey,
                            OperationTypeKey,
                            InsertJsonDataKey,
                            DeleteIdsKey,
                            };
                        }
                    }
                }

                return _reservedKeys;
            }
        }


        public static bool GetSortField(NameValueCollection nameValueCollection, out string value)
        {
            value = nameValueCollection[RequestHelper.SortFieldKey];
            return !string.IsNullOrEmpty(value);
        }

        public static bool GetSortDesc(NameValueCollection nameValueCollection, out bool value)
        {
            value = false;
            string strValue = nameValueCollection[RequestHelper.SortByDescKey];
            try
            {
                value = Convert.ToBoolean(strValue);
            }
            catch (Exception ex)
            {
                LogHelper.WriteLog("GetSortDesc", ex);
                return false;
            }

            return true;
        }

        public static bool GetPage(NameValueCollection nameValueCollection, out int pageNo, out int pageSize)
        {
            pageNo = 1;
            pageSize = 0;
            string pageSizeStr = nameValueCollection[RequestHelper.PageSizeKey];
            if (string.IsNullOrEmpty(pageSizeStr))
            {
                return false;
            }

            try
            {
                pageSize = Convert.ToInt32(pageSizeStr);
                if (pageSize < 0)
                {
                    return false;
                }
            }
            catch (Exception ex)
            {
                LogHelper.WriteLog("GetPage", ex);
                return false;
            }

            string pageIndexStr = nameValueCollection[RequestHelper.PageNoKey];
            if (string.IsNullOrEmpty(pageIndexStr))
            {
                return true;
            }

            try
            {
                pageNo = Convert.ToInt32(pageIndexStr);
                if (pageNo < 1)
                {
                    pageNo = 1;
                }
            }
            catch (Exception ex)
            {
                LogHelper.WriteLog("GetPage", ex);
            }

            return true;
        }

        public static bool GetEnumArray<TEnum>(NameValueCollection nameValues, string name, out TEnum[] values)
        {
            values = null;
            string strValues = nameValues[name];
            if (strValues == null)
            {
                return false;
            }

            try
            {
                values = strValues.Split(ParamsSeparator).Select(item => (TEnum)Enum.Parse(typeof(TEnum), item)).ToArray();
            }
            catch(Exception ex)
            {
                LogHelper.WriteLog("GetEnumArray", ex);
            }

            return values != null && values.Length != 0;
        }

        public static bool GetEnum<TEnum>(NameValueCollection nameValues, string name, out TEnum value)
        {
            value = default(TEnum);
            TEnum[] values;
            bool result = GetEnumArray(nameValues, name, out values);
            if (!result)
            {
                return false;
            }

            value = values[0];
            return true;
        }

        public static bool GetStringArray(NameValueCollection nameValues, string name, out string[] values)
        {
            values = null;
            string strValues = nameValues[name];
            if (strValues == null)
            {
                return false;
            }

            values = strValues.Split(ParamsSeparator);
            return values.Length != 0;
        }

        public static bool GetString(NameValueCollection nameValues, string name, out string value)
        {
            value = null;
            string[] values;
            bool result = GetStringArray(nameValues, name, out values);
            if (!result)
            {
                return false;
            }

            value = values[0];
            return true;
        }

        public static bool GetInt32Array(NameValueCollection nameValues, string name, out int[] values)
        {
            values = null;
            string strValues = nameValues[name];
            if (string.IsNullOrEmpty(strValues))
            {
                return false;
            }

            try
            {
                values = strValues.Split(ParamsSeparator).Select(item => Convert.ToInt32(item)).ToArray();
            }
            catch (Exception ex)
            {
                LogHelper.WriteLog("GetInt32Array", ex);
            }

            return values!= null && values.Length != 0;
        }

        public static bool GetInt32(NameValueCollection nameValues, string name, out int value)
        {
            value = -1;
            int[] values;
            bool result = GetInt32Array(nameValues, name, out values);
            if (!result)
            {
                return false;
            }

            value = values[0];
            return true;
        }

        public static bool GetDateTime(NameValueCollection nameValues, string name, out DateTime dt)
        {
            dt = DateTime.Now;
            string strValue = nameValues[name];
            if (string.IsNullOrEmpty(strValue))
            {
                return false;
            }

            try
            {
                dt = Convert.ToDateTime(strValue);
            }
            catch (Exception ex)
            {
                LogHelper.WriteLog("GetDateTime", ex);
                return false;
            }

            return true;
        }

        public static bool GetDateTimeRange(NameValueCollection nameValues, string name, out DateTime startTime, out DateTime endTime)
        {
            startTime = EarliestDateTime;
            endTime = DateTime.Now;
            string strValues = nameValues[name];
            if (string.IsNullOrEmpty(strValues))
            {
                return false;
            }

            DateTime[] values = null;
            try
            {
                values = strValues.Split(ParamsSeparator).Select(item => Convert.ToDateTime(item)).ToArray();
            }
            catch (Exception ex)
            {
                LogHelper.WriteLog("GetDateTimeRange", ex);
            }

            if (values == null || values.Length == 0)
            {
                return false;
            }

            startTime = values[0];
            if (values.Length > 1)
            {
                endTime = values[1];
            }

            return true;
        }

        public static bool GetDoubleRange(NameValueCollection nameValues, string name, out double start, out double end)
        {
            start = 0;
            end = 100000;
            string strValues = nameValues[name];
            if (string.IsNullOrEmpty(strValues))
            {
                return false;
            }

            double[] values = null;
            try
            {
                values = strValues.Split(ParamsSeparator).Select(item => Convert.ToDouble(item)).ToArray();
            }
            catch (Exception ex)
            {
                LogHelper.WriteLog("GetDoubleRange", ex);
            }

            if (values == null || values.Length == 0)
            {
                return false;
            }

            start = values[0];
            if (values.Length > 1)
            {
                end = values[1];
            }

            return true;
        }

        public static bool GetDouble(NameValueCollection nameValues, string name, out double value)
        {
            value = 0;
            string strValue = nameValues[name];
            if (string.IsNullOrEmpty(strValue))
            {
                return false;
            }

            try
            {
                value = Convert.ToDouble(strValue);
            }
            catch (Exception ex)
            {
                LogHelper.WriteLog("GetDouble", ex);
                return false;
            }

            return true;
        }

        public static bool IsReservedKey(string key)
        {
            return ReservedKeys.Contains(key, IgnoreCaseEqualityComparer.Default);
        }

        public static bool GetBool(NameValueCollection nameValues, string name, out bool value)
        {
            value = false;
            string strValue = nameValues[name];
            if (string.IsNullOrEmpty(strValue))
            {
                return false;
            }

            try
            {
                value = Convert.ToBoolean(strValue);
            }
            catch (Exception ex)
            {
                LogHelper.WriteLog("GetBool", ex);
                return false;
            }

            return true;
        }

        public static bool GetOperationType(NameValueCollection qs, out OperationType operation)
        {
            operation = OperationType.SelectAll;
            string methodStr = qs[OperationTypeKey];
            if (string.IsNullOrEmpty(methodStr))
            {
                return false;
            }

            if (string.Equals(methodStr, SelectOperationKey, StringComparison.InvariantCultureIgnoreCase))
            {
                operation = OperationType.Select;
                return true;
            }

            if (string.Equals(methodStr, SelectAllOperationKey, StringComparison.InvariantCultureIgnoreCase))
            {
                operation = OperationType.SelectAll;
                return true;
            }

            if (string.Equals(methodStr, UpdateOperationKey, StringComparison.InvariantCultureIgnoreCase))
            {
                operation = OperationType.Update;
                return true;
            }

            if (string.Equals(methodStr, InsertOperationKey, StringComparison.InvariantCultureIgnoreCase))
            {
                operation = OperationType.Insert;
                return true;
            }

            if (string.Equals(methodStr, DeleteOperationKey, StringComparison.InvariantCultureIgnoreCase))
            {
                operation = OperationType.Delete;
                return true;
            }

            return false;
        }
    }
}